<?php
/**
 * Created by PhpStorm.
 * User: fuyu
 * Date: 2018/6/25
 * Time: 下午5:23
 */

namespace App\Logic;


use App\Models\OrderSource;
use Illuminate\Support\Facades\Cache;
use PhpOffice\PhpSpreadsheet\IOFactory;
use PhpOffice\PhpSpreadsheet\Spreadsheet;

abstract class BaseExport
{

    protected $sourceName = null;   //source的名称，与order_source表的source对应
    protected $sourceId = null;   //source的id，与order_source表的source对应

    protected $sourceTitle = [];  //源文件的标题栏
    protected $targetTitle = [];  //目标文件的标题栏

    /**
     * @var Spreadsheet
     */
    protected $workbook;
    protected $sourceData ;    //表格中数据
    protected $targetData;    //待导出数据
    protected $errorData;

    protected $sourcePath;
    protected $targetPath;

    private $colors = [
        'DC143C',  //红
        'FF00FF', //杨红
        '9370DB',  //紫色
        '1E90FF',  //蓝色
        '7FFFAA',  //绿色
        'FFFF00',  //黄色
        'FFA500',  //橙色
    ];

    public function __construct()
    {
        $this->getSourceId();
    }

    public function getTargetData()
    {
        return $this->targetData;
    }

    public function getErrorData()
    {
        return $this->errorData;
    }

    public function hasError()
    {
        return !empty($this->errorData);
    }

    public function getColor()
    {
        static $index = 0;
        if ($index == count($this->colors)) {
            $index = 0;
        }
        return $this->colors[$index++];
    }

    /**
     * 通过sourename找到sourceId
     */
    private function getSourceId ()
    {
        $row = OrderSource::where('name',$this->sourceName)->first();
        if (empty($row)) {
            throw new \Exception("找不到该来源'{$this->sourceName}'，请确认");
        }
        $this->sourceId = $row['id'];
    }

    public function load($sourcePath)
    {
        $this->sourcePath = $sourcePath;
        $this->setSourceTitle();
        $this->workbook = IOFactory::load($sourcePath);
        $this->loadData();
    }

    /**
     * 将导入的数据转换，并放入缓存
     */
    public function transform()
    {
        $this->transferData();
        $cacheKey = uniqid();
        Cache::set($cacheKey,['sourcePath'=>$this->sourcePath,'targetData'=>$this->targetData,'errorData'=>$this->errorData],86400);
        return $cacheKey;
    }

    private function loadFromCache($cacheKey)
    {
        $cacheData = Cache::get($cacheKey);
        if (empty($cacheData)) {
            throw new \Exception('获取不到相应的缓存数据');
        }
        $this->sourcePath = $cacheData['sourcePath'];
        $this->targetData = $cacheData['targetData'];
        $this->errorData = $cacheData['errorData'];
    }

    public function writeToExcel($cacheKey,$targetPath = '')
    {
        $this->loadFromCache($cacheKey);
        if (!$targetPath) {
            $this->setTargetPath();
        } else {
            $this->targetPath = $targetPath;
        }

        $this->setTargetTitle();
        $this->toExcel();
        //返回路径
        preg_match('^.*(/exports/.*$)^',$this->targetPath,$matches);
        return $_SERVER['HTTP_HOST'].$matches[1];
    }

    private function setTargetPath()
    {
        $fname = '导出-'.date('YmdHis').'.xlsx';
        $path = storage_path('exports/'.date('Y-m-d').'/');
        if (!file_exists($path)) {
            mkdir($path);
        }
        $this->targetPath = $path.$fname;
    }

    public function getSourceTitle () {
        return $this->sourceTitle;
    }

    public function getTargetTitle () {
        return $this->targetTitle;
    }

    public function mappingCell ($row,$column)
    {
        //除了标题栏，其他从第2（B）行算起
        return chr(66+$row).($column+1);
    }

    public function addError($row,$message)
    {
        $this->errorData[] = [
            'row' => $row,
            'message' => $message
        ];
    }

    abstract protected function setSourceTitle ();

    abstract protected function setTargetTitle ();

    /**
     * 读取源excel
     * @return mixed
     */
    abstract protected function loadData();

    /**
     * 按照excel的目标文件设置导出的数据
     * @return mixed
     */
    abstract protected function transferData();

    /**
     * 将导出的数据写入excel文件中
     * @return mixed
     */
    abstract protected function toExcel();
}